package KAs;

import java.util.ArrayList;
import java.util.Random;
import java.util.Scanner;

/**
 * ATM系统的入口类
 */
public class ATMSystem {
    public static void main(String[] args) {
        //1.定义账户类
        //2.定义一个集合容器，负责存储全部账户对象，进行相应操作
        ArrayList<Account> accounts = new ArrayList<>();
        Scanner sc = new Scanner(System.in);
        //3.展示系统的首页
        while (true) {
            System.out.println("=======================欢迎使用ATM系统==================");
            System.out.println("1.登录账户");
            System.out.println("2.注册账户");
            System.out.println("请输入您的操作：");
            int common = sc.nextInt();
            switch (common) {
                case 1:
                    //登录操作
                    login(accounts, sc);
                    break;

                case 2:
                    //注册操作
                    register(accounts, sc);
                    break;

                default:
                    System.out.println("您的输入操作有误，请重新输入！！！");
            }
        }
    }

    /**
     * 定义一个方法，实现登录功能
     *
     * @param accounts
     * @param sc
     */
    private static void login(ArrayList<Account> accounts, Scanner sc) {
        System.out.println("==================系统登录操作=================");
        //1.判断当时系统是否有账户
        if (accounts.size() == 0) {
            System.out.println("当前系统无任何账户，请先开户！！！");
            return;
        }

        //2.让用户输入卡号，根据卡号查询用户是否存在
        while (true) {
            System.out.println("请输入您的卡号：");
            String cardId = sc.next();

            //判断卡号是否存在：根据卡号去账户集合中查询账户对象
            Account acc = judgeCardId(accounts, cardId);
            if (acc != null) {
                while (true) {
                    System.out.println("请您输入密码：");
                    String password = sc.next();
                    if (acc.getPassword().equals(password)) {
                        System.out.println(acc.getUsername() + "先生/女生密码正确，登陆成功！！！");

                        //需要显示登录后的操作页
                        showUserCommand(sc, acc, accounts);
                        return;//结束登录后的操作页，回到首页
                    } else {
                        System.out.println("密码不正确，请您重新输入！！！");
                    }
                }
            } else {
                System.out.println("您输入的卡号不存在，请重新输入！！！");
            }
        }
    }

    /**
     * 登录成功后展示的页面
     */
    private static void showUserCommand(Scanner sc, Account acc, ArrayList<Account> accounts) {
        while (true) {
            System.out.println("===================用户登录操作页====================");
            System.out.println("1.查询账户");
            System.out.println("2.存款");
            System.out.println("3.取款");
            System.out.println("4.修改密码");
            System.out.println("5.退出");
            System.out.println("6.注销账户");
            System.out.println("请输入您的操作：");
            int command = sc.nextInt();

            switch (command) {
                case 1:
                    //查询账户
                    showAccount(acc);
                    break;
                case 2:
                    //存款
                    deposit(acc, sc);
                    break;
                case 3:
                    //取款
                    withdrawMoney(acc, sc);
                    break;
                case 4:
                    //转账
                    transfer(acc, sc,accounts);
                    break;
                case 5:
                    //修改密码
                    changePassword(acc, sc);
                    return;
                case 6:
                    //退出
                    System.out.println("退出成功！！！");
                    return;//退出操作页
                case 7:
                    //注销账户
                    if (logout(acc, sc, accounts)) {
                        return;
                    } else {
                        break;
                    }
                default:
                    System.out.println("您输入的操作命令不正确！！！");
            }
        }
    }

    /**
     * 注销账户
     *
     * @param acc
     * @param sc
     * @param accounts
     */
    private static boolean logout(Account acc, Scanner sc, ArrayList<Account> accounts) {
        System.out.println("====================注销账户===================");
        System.out.println("您确定要销户吗？y/n");
        String s = sc.next();
        switch (s) {
            case "y":
                if (acc.getMoney() > 0) {
                    System.out.println("账户还有余额，不可销户！！！");
                } else {
                    accounts.remove(acc);//注销账户
                    System.out.println("销户成功！！！");
                    return true;
                }
                break;
            default:
                System.out.println("很好，当前用户继续保留！！！");
        }
        return false;
    }

    /**
     * 定义一个方法，实现用户修改功能
     *
     * @param acc
     * @param sc
     */
    private static void changePassword(Account acc, Scanner sc) {
        System.out.println("=====================修改密码==================");
        while (true) {
            System.out.println("请" + acc.getUsername() + "先生/女生输入要修改的密码：");
            String password = sc.next();
            System.out.println("请" + acc.getUsername() + "先生/女生确认要修改的密码：");
            String okpassword = sc.next();
            if (okpassword.equals(password)) {
                acc.setPassword(password);
                System.out.println("修改密码成功！！！");
                System.out.println("请重新登录账户！！！");
                return;
            } else {
                System.out.println("您输入的两次密码不一致，请重新输入！！！");
            }
        }
    }

    /**
     * 定义一个方法，实现转账用户功能
     *
     * @param acc
     * @param sc
     */
    private static void transfer(Account acc, Scanner sc,ArrayList<Account> accounts) {
        System.out.println("======================转账=====================");
        String cardid= null;
        //判断输入的卡号是否存在
        while (true) {
            System.out.println("请输入您要转账的卡号：");
            cardid = sc.next();
            if(judgeCardId(accounts,cardid)==null){
                System.out.println("您输入的卡号不存在，请重新输入！！！");
            }else if(acc.getCardId().equals(cardid)){
                System.out.println("不可给自己转账，请重新输入！！！");
            }else {
                break;
            }
        }
        //遍历找到要转账的卡号
        for (int i = 0; i < accounts.size(); i++) {
            Account acc1=accounts.get(i);
            if (acc1.getCardId().equals(cardid)) {
                //输入姓名，判断是否正确
                while (true) {
                    System.out.println("请您补全姓名：");
                    String s1=acc1.getUsername().substring(0,1);
                    String s2=acc1.getUsername().substring(2);
                    System.out.println(s1+"*"+s2);
                    String name=sc.next();
                    if (acc1.getUsername().equals(name)) {
                        break;
                    }else {
                        System.out.println("您输入的姓名有误，请重新输入！！！");
                    }
                }
                //判断金额
                if (acc.getMoney() == 0) {
                    System.out.println("您现在余额为0，请先存款后，才可以转账！！！");
                    return;
                }
                while (true) {
                    System.out.println("请输入您的转账金额：");
                    double money = sc.nextDouble();
                    if (money <= acc.getAmount() && money <= acc.getMoney()) {
                        acc.setMoney(acc.getMoney() - money);
                        acc1.setMoney(acc1.getMoney()+money);
                        System.out.println("转账成功！！！");
                        break;
                    } else if (money > acc.getMoney()) {
                        System.out.println("您的存款金额不足，请重新输入！！！");
                    }else if (money > acc.getAmount()) {
                        System.out.println("您的转账金额超出限额,请重新输入！！！");
                    }
                }
            }
        }

    }

    /**
     * 定义一个方法，实现取款功能，并输出查询账户
     *
     * @param acc
     * @param sc
     */
    private static void withdrawMoney(Account acc, Scanner sc) {
        System.out.println("======================取款======================");
        if (acc.getMoney() == 0) {
            System.out.println("您现在余额为0，请先存款后，才可以取款！！！");
            return;
        }
        while (true) {
            System.out.println("请输入您的取款金额：");
            double money = sc.nextDouble();
            if (money <= acc.getAmount() && money <= acc.getMoney()) {
                acc.setMoney(acc.getMoney() - money);
                System.out.println("取款成功！！！");
                break;
            } else if (money > acc.getAmount()) {
                System.out.println("您的取款金额超出限额,请重新输入！！！");
            } else if (money > acc.getMoney()) {
                System.out.println("您的存款金额不足，请重新输入！！！");
            }
        }
        showAccount(acc);
    }

    /**
     * 定义一个方法，实现存款功能，并输出查询账户
     *
     * @param acc
     */
    private static void deposit(Account acc, Scanner sc) {
        System.out.println("======================存款======================");
        System.out.println("请输入您要存款的金额：");
        double money = sc.nextDouble();
        acc.setMoney(acc.getMoney() + money);
        System.out.println("存款成功！！！");
        showAccount(acc);
    }

    /**
     * 定义一个方法，实现登录后查询账户的功能
     *
     * @param acc
     */
    private static void showAccount(Account acc) {
        System.out.println("==================查询账户================");
        System.out.println("卡号：" + acc.getCardId());
        System.out.println("户主：" + acc.getUsername());
        System.out.println("余额：" + acc.getMoney());
        System.out.println("限额：" + acc.getAmount());
    }

    /**
     * 定义一个方法，实现用户开户功能
     *
     * @param accounts
     * @param sc
     */
    private static void register(ArrayList<Account> accounts, Scanner sc) {
        System.out.println("=================系统开户操作===================");
        //1.创建一个Account账户类，用于封装账户信息（用户名，密码，卡号）
        Account account = new Account();

        //2.录入当前账户信息，注入到账户对象中去
        //2.1 用户名
        System.out.println("请输入您的用户名：");
        String username = sc.next();
        account.setUsername(username);

        //2.2 密码
        while (true) {
            System.out.println("请输入您的账户密码：");
            String password = sc.next();
            System.out.println("请您确认密码：");
            String okpassword = sc.next();
            if (okpassword.equals(password)) {
                account.setPassword(okpassword);
                break;//要记得跳出循环！！！
            } else {
                System.out.println("您两次输入的密码不同，请重新输入！！！");
            }
        }

        //2.3 限额
        while (true) {
            System.out.println("请输入您最大支付额度：");
            double amount = sc.nextDouble();
            if (amount > 0) {
                account.setAmount(amount);
                break;
            } else {
                System.out.println("您输入的不可为负数，请重新输入！！！");
            }
        }

        //2.3 卡号（运用一个方法，使得其随机生成一个8位的卡号，且不可重复的卡号）
        String cardId = getRandomCardId(accounts);
        System.out.println("恭喜" + username + "先生/女生，开户成功!!!\n您的卡号为：" + cardId);
        account.setCardId(cardId);

        //3.把账户对象添加到集合中去
        accounts.add(account);
    }

    /**
     * 定义一个方法，随机生成一个8位数的卡号
     *
     * @param accounts
     */
    private static String getRandomCardId(ArrayList<Account> accounts) {
        Random r = new Random();
        while (true) {
            String cardId = "";

            for (int i = 0; i < 8; i++) {
                cardId += r.nextInt(10);
            }
            //定义方法，判断是否有重复的（只需看这个卡号，是否有账户即可）
            Account acc = judgeCardId(accounts, cardId);
            if (acc == null) {
                return cardId;
            }
        }

    }

    /**
     * 查询该卡号是否有账户
     *
     * @param accounts
     * @param carId
     */
    private static Account judgeCardId(ArrayList<Account> accounts, String carId) {
        for (int i = 0; i < accounts.size(); i++) {
            Account acc = accounts.get(i);
            if (acc.getCardId().equals(carId)) {
                return acc;
            }
        }

        return null;//查无此账户
    }
}
